package org.maxgroundstation.groundstation.view.overlay;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;

/**
 * A utility class for displaying overlay text.
 * @author Scott Davis
 * 
 * Copyright (C) 2011  Scott Davis
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
public final class TextDisplayUtil {

    // Text alignment position options.
    public static final int LEFT_HORIZONTAL_ALIGNMENT = 0;
    public static final int CENTER_HORIZONTAL_ALIGNMENT = 1;
    public static final int RIGHT_HORIZONTAL_ALIGNMENT = 2;
    public static final int TOP_VERTICAL_ALIGNMENT = 0;
    public static final int MIDDLE_VERTICAL_ALIGNMENT = 1;
    public static final int BOTTOM_VERTICAL_ALIGNMENT = 2;
    
    // Default text and outline colors.
    private static final Color DEFAULT_TEXT_COLOR = Color.GREEN;
    private static final Color DEFAULT_OUTLINE_COLOR = new Color(0, 0, 0, 127);
    
    // Private default constructor for utility class.
    private TextDisplayUtil() {};
    
    /**
     * Draws the text at a given X,Y position with default values for alignment, font, and color.
     * @param text the text string.
     * @param xPos the X position.
     * @param yPos the Y position.
     * @param g the graphics context.
     */
    public static void drawText(String text, int xPos, int yPos, Graphics g) {
        drawText(text, xPos, yPos, CENTER_HORIZONTAL_ALIGNMENT, MIDDLE_VERTICAL_ALIGNMENT, 
                DEFAULT_TEXT_COLOR, true, DEFAULT_OUTLINE_COLOR, g.getFont(), g);
    }
    
    /**
     * Draws the text at a given X,Y position with default values for alignment, font, and color.
     * @param text the text string.
     * @param xPos the X position.
     * @param yPos the Y position.
     * @param horizontalAlignment the horizontal alignment (see static values).
     * @param verticalAlignment the vertical alignment (see static values).
     * @param g the graphics context.
     */
    public static void drawText(String text, int xPos, int yPos, int horizontalAlignment, 
            int verticalAlignment, Graphics g) {
        drawText(text, xPos, yPos, horizontalAlignment, verticalAlignment, 
                DEFAULT_TEXT_COLOR, true, DEFAULT_OUTLINE_COLOR, g.getFont(), g);
    }
    
    /**
     * Draws the text at a given X,Y position.
     * @param text the text string.
     * @param xPos the X position.
     * @param yPos the Y position.
     * @param horizontalAlignment the horizontal alignment (see static values).
     * @param verticalAlignment the vertical alignment (see static values).
     * @param textColor the text color.
     * @param drawOutline should the text outline be drawn.
     * @param textOutlineColor the outline color.
     * @param textFont the font.
     * @param g the graphics context.
     */
    public static void drawText(String text, int xPos, int yPos, int horizontalAlignment, 
            int verticalAlignment, Color textColor, boolean drawOutline, 
            Color textOutlineColor, Font textFont, Graphics g) {
        
        Graphics2D g2d = (Graphics2D) g;
        
        // Save original graphics transforms.
        AffineTransform saveTransform = g2d.getTransform();
        
        // Save original graphics font.
        Font saveFont = g2d.getFont();
        
        // Determine bounds.
        g2d.setFont(textFont);
        TextLayout textLayout = new TextLayout(text, textFont, g2d.getFontRenderContext());
        Rectangle2D bounds = textLayout.getBounds();
        
        // Determine translation X position.
        int translationX = 0;
        switch (horizontalAlignment) {
            case LEFT_HORIZONTAL_ALIGNMENT:   translationX = xPos;
                                              break;
            case CENTER_HORIZONTAL_ALIGNMENT: translationX = xPos - (int) (bounds.getWidth() / 2D);
                                              break;
            case RIGHT_HORIZONTAL_ALIGNMENT:  translationX = xPos - (int) bounds.getWidth();
                                              break;
            default:                          translationX = 0;
        }
        
        // Determine translation Y position.
        int translationY = 0;
        switch (horizontalAlignment) {
            case TOP_VERTICAL_ALIGNMENT:    translationY = yPos;
                                            break;
            case MIDDLE_VERTICAL_ALIGNMENT: translationY = yPos - (int) (bounds.getHeight() / 2D);
                                            break;
            case BOTTOM_VERTICAL_ALIGNMENT: translationY = yPos - (int) bounds.getHeight();
                                            break;
            default:                        translationY = 0;
        }
        
        // Apply graphic transforms for text.
        AffineTransform newTransform = new AffineTransform();
        newTransform.translate(translationX, translationY);
        Shape textShape = textLayout.getOutline(newTransform);
        
        if (drawOutline) {
            // Draw text outline.
            Stroke saveStroke = g2d.getStroke();
            g2d.setColor(textOutlineColor);
            g2d.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2d.draw(textShape);
            g2d.setStroke(saveStroke);
        }
        
        // Fill label
        g2d.setColor(textColor);
        g2d.fill(textShape);
        
        // Restore original graphics font.
        g2d.setFont(saveFont);
        
        // Restore original graphics transforms.
        g2d.setTransform(saveTransform);
    }
}